/*
 * Fichier: BookTreeModel.java
 * Crée le: 20 septembre 2007.
 * Modifié: 14 février 2009.
 * Auteurs: Sébastien ESTIENNE.
 * SiteWeb: http://www.prog-info.org/
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package javaexos.gui;



import java.util.Collections;

import javaexos.model.BookModel;
import javaexos.model.ChapterModel;
import javaexos.model.ExerciseModel;

import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;



/**
 * <p>Le modèle utilisé par l'abre de livre des exercices.</p>
 * @author Sébastien ESTIENNE.
 */
public class BookTreeModel implements TreeModel
{
   /** Le livre d'exercices. */
   private BookModel book;


   /**
    * <p>Constructeur.</p>
    * @param book Le livre des exercices.
    */
   public BookTreeModel(BookModel book)
   {
      this.book = book;
   }


   /**
    * <p>Retourne la racine de l'arbre.</p>
    * @return Renvoie la racine de l'arbre.
    */
   public Object getRoot()
   {
      return this.book;
   }


   /**
    * <p>Retourne le noeud enfant numéro <code>index</code> du noeud noeud parent spécifié.</p>
    * @param parent Un noeud dans l'arbre, obtenu à partir des données source.
    * @param index L'index du noeud enfant.
    * @return Renvoie le noeud enfant numéro <code>index</code> du noeud noeud parent.
    */
   public Object getChild(Object parent, int index)
   {
      if(parent instanceof BookModel)
      {
         return ((BookModel) parent).getChapters().get(index);
      }
      else if(parent instanceof ChapterModel)
      {
         return ((ChapterModel) parent).getExercises().get(index);
      }
      return null;
   }


   /**
    * <p>Retourne le nombre de noeuds enfants du noeud parent.</p>
    * @param parent Un noeud dans l'arbre, obtenu à partir des données source.
    * @return Renvoie le nombre de noeuds enfants du noeud parent.
    */
   public int getChildCount(Object parent)
   {
      if(parent instanceof BookModel)
      {
         return ((BookModel) parent).getChapters().size();
      }
      else if(parent instanceof ChapterModel)
      {
         return ((ChapterModel) parent).getExercises().size();
      }
      return 0;
   }


   /**
    * <p>Retourne l'index du noeud enfant dans le noeud parent. Retourne -1 si l'un des paramètres
    * n'appartient pas au modèle ou si le noeud enfant n'a pas été trouvé dans le noeud parent.</p>
    * @param parent Un noeud dans l'arbre, obtenu à partir des données source.
    * @param child Le noeud enfant recherché.
    * @return Renvoie l'index du noeud enfant dans le noeud parent.
    */
   public int getIndexOfChild(Object parent, Object child)
   {
      if(parent instanceof BookModel && child instanceof ChapterModel)
      {
         return Collections.binarySearch(((BookModel) parent).getChapters(), (ChapterModel) child);
      }
      else if(parent instanceof ChapterModel)
      {
         return Collections.binarySearch(((ChapterModel) parent).getExercises(),
               (ExerciseModel) child);
      }
      return -1;
   }


   /**
    * <p>Retourne true si le noeud est une feuille, false sinon.</p>
    * @param node Un noeud dans l'arbre, obtenu à partir des données source.
    * @return Renvoie true si le noeud est une feuille, false sinon.
    */
   public boolean isLeaf(Object node)
   {
      return node instanceof ExerciseModel;
   }


   /**
    * <p>Invoqué lorsque l'utilisateur a modifié la valeur d'un élément identifié par le chemin
    * vers le noeud avec une nouvelle valeur.</p>
    * @param path Le chemin vers le noeud que l'utilisateur a modifié.
    * @param newValue la nouvelle valeur pour le <code>TreeCellEditor</code>.
    */
   public void valueForPathChanged(TreePath path, Object newValue)
   {
      // L'arbre n'est pas éditable.
   }


   /**
    * <p>Ajoute un écouteur pour l'événement <code>TreeModelEvent</code>.
    * @param l L'écouteur à ajouter.
    */
   public void addTreeModelListener(TreeModelListener l)
   {
      // Non utilisé.
   }


   /**
    * <p>Supprime l'écouteur spécifié pour l'événement <code>TreeModelEvent</code>.
    * @param l L'écouteur à supprimer.
    */
   public void removeTreeModelListener(TreeModelListener l)
   {
      // Non utilisé.
   }
}
